feat: add EmpirioLabs integration with ChatEmpirioLabs node#6509
feat: add EmpirioLabs integration with ChatEmpirioLabs node#6509Adam-Dalloul wants to merge 1 commit into
Conversation
Adds a dedicated Chat Model node for EmpirioLabs, an OpenAI-compatible inference API. The node wraps ChatOpenAI with the EmpirioLabs base URL (https://api.empiriolabs.ai/v1), a password credential, and an asyncOptions Model Name loader that lists chat-capable models live from GET /v1/models (with a static fallback when the catalog is unreachable). Streaming is enabled by registering chatEmpirioLabs in the stream-valid chat model list. Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request introduces support for EmpirioLabs chat models by adding the EmpirioLabsApi credential, the ChatEmpirioLabs chat model node, and its corresponding SVG icon, as well as enabling streaming support for the new node. Feedback on the implementation highlights two issues in ChatEmpirioLabs.ts: first, the listModels method should dynamically use the user-configured basepath instead of a hardcoded default URL; second, the optional temperature parameter should be parsed and assigned conditionally to prevent passing NaN to the underlying ChatOpenAI instance.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| async listModels(_: INodeData, __?: ICommonObject): Promise<INodeOptionsValue[]> { | ||
| try { | ||
| const response = await axios.get(`${DEFAULT_BASE_URL}/models`) |
There was a problem hiding this comment.
The listModels method currently queries the hardcoded DEFAULT_BASE_URL to fetch the model list. If a user configures a custom basepath (e.g., for a local proxy, a self-hosted gateway, or an alternative endpoint), the model loader will still attempt to fetch models from the default URL. This can result in fetching the wrong models or failing to fetch models entirely in restricted or air-gapped environments. We should retrieve and use the user-configured basepath from nodeData.inputs if available.
| async listModels(_: INodeData, __?: ICommonObject): Promise<INodeOptionsValue[]> { | |
| try { | |
| const response = await axios.get(`${DEFAULT_BASE_URL}/models`) | |
| async listModels(nodeData: INodeData, __?: ICommonObject): Promise<INodeOptionsValue[]> { | |
| try { | |
| const basePath = (nodeData.inputs?.basepath as string) || DEFAULT_BASE_URL | |
| const response = await axios.get(`${basePath}/models`) |
| const obj: ChatOpenAIFields = { | ||
| temperature: parseFloat(temperature), | ||
| model: modelName, | ||
| apiKey: empirioLabsApiKey, | ||
| openAIApiKey: empirioLabsApiKey, | ||
| streaming: streaming ?? true | ||
| } |
There was a problem hiding this comment.
If temperature is not provided (since it is optional), parseFloat(temperature) will evaluate to NaN. Passing NaN as temperature to ChatOpenAI can cause API requests to fail or behave unexpectedly. It is safer to conditionally add temperature to the configuration object only if it is defined and not an empty string, using a loose equality check (!= null) to handle both null and undefined.
| const obj: ChatOpenAIFields = { | |
| temperature: parseFloat(temperature), | |
| model: modelName, | |
| apiKey: empirioLabsApiKey, | |
| openAIApiKey: empirioLabsApiKey, | |
| streaming: streaming ?? true | |
| } | |
| const obj: ChatOpenAIFields = { | |
| model: modelName, | |
| apiKey: empirioLabsApiKey, | |
| openAIApiKey: empirioLabsApiKey, | |
| streaming: streaming ?? true | |
| } | |
| if (temperature != null && temperature !== '') { | |
| obj.temperature = parseFloat(temperature) | |
| } |
References
- In JavaScript/TypeScript, use loose equality (
== null) as a standard idiom for a 'nullish' check that covers bothnullandundefined.
What
Adds a dedicated ChatEmpirioLabs Chat Model node and an EmpirioLabs API credential. EmpirioLabs is an OpenAI compatible inference platform that exposes frontier chat models (Qwen3.7, DeepSeek V4, GLM-5.1, Kimi K2.7 Code, MiniMax M3, and more) through a single API.
Changes
packages/components/nodes/chatmodels/ChatEmpirioLabs/ChatEmpirioLabs.ts(new): wrapsChatOpenAIwithconfiguration.baseURL = https://api.empiriolabs.ai/v1. Includes anasyncOptionsModel Name loader (listModels) that lists chat-capable models live fromGET /v1/models, with a static fallback when the catalog is unreachable. Streaming is on by default; Temperature, Max Tokens, Top P, Frequency/Presence Penalty, Timeout, Base Path, and Base Options are exposed (same surface as the existing Cerebras / OpenRouter nodes).packages/components/credentials/EmpirioLabsApi.credential.ts(new): single password field for the EmpirioLabs API key.packages/components/nodes/chatmodels/ChatEmpirioLabs/empiriolabs.svg(new): node icon.packages/server/src/utils/index.ts: registerchatEmpirioLabsin the stream-valid Chat Models list so streaming works.Notes
Authorization: Bearer <key>(handled byChatOpenAIfrom the credential). No vendor attribution / branding headers are sent.Model Namedefaults toqwen3-7-plus; users can pick any model returned by the live catalog or type a slug.Verification
tsc --noEmitonpackages/components: no errors from the new files (the only errors present are pre-existing missing-module errors insrc/storage/*andsrc/utils.tsunrelated to this change).eslintandprettier --checkpass on both new files.Related docs
Companion documentation PR: FlowiseAI/FlowiseDocs#220